/**
 * @Author       : Mo 2427995270@qq.com
 * @Date         : 2023-03-14 15:31:41
 * @LastEditTime : 2024-01-26 15:38:11
 * @FilePath     : \KT-2020-CT\libs\move_average.h
 * @Description  : 移动平均算法库
 * @Version      : V1.0
 * @History      :
 * @Note         :
 */

#ifndef __move_average_H__
#define __move_average_H__

/***************************************Includes***********************************/



/*************************************Public Macros********************************/
// #define


/***********************************Public Statement*******************************/
typedef struct {
    int quantity;        // 数据数量
    double *in;          // 指向待平均数据的缓冲区，手动初始化该结构体或调用move_ave_wma_d_init()初始化
    double *out;         // 指向平均数据的缓冲区，手动初始化该结构体或调用move_ave_wma_d_init()初始化
    int start_idx;       // 指向in最老数据 若手动初始化 为0
    int end_idx;         // 指向in最新数据 若手动初始化 为0
    int out_idx;         // 输出缓冲区最新数据的索引 用户不要更改
    double _last_result; // 指数移动平均上次均值结果，计算结束后为本次结果，新一轮计算开始为上次结果
    double _series;      // 指数移动平均的修正无穷级数
} move_ave_d_t;


/***********************************Public Functions*******************************/

/**
 * @brief 初始化结构
 * @param  type
 * @param  quantity                平均窗口大小
 * @return int 0 成功  -1 失败
 * @note 使用该函数初始化，在不再使用结构后请调用move_ave_wma_d_free()释放资源
 */
int move_ave_d_init(move_ave_d_t *type, int quantity);
/**
 * @brief 释放结构成员占用的资源
 * @param  type
 * @note null
 */
void move_ave_d_free(move_ave_d_t *type);
/**
 * @brief 添加新值
 * @param  type
 * @param  new              新值
 * @return int 0 添加成功  -1 失败
 * @note 首次添加，则整个in缓冲区将被该值覆盖
 */
int move_ave_d_add(move_ave_d_t *type, double new);
/**
 * @brief 计算简单移动平均
 * @param  type
 * @param  T                窗口大小 最大等于 quantity
 * @param  result           计算结果
 * @return int
 * @note null
 */
int move_ave_sma_d(move_ave_d_t *type, int T, double *result);
/**
 * @brief 计算加权移动平均
 * @param  type
 * @param  T                窗口大小 最大等于 quantity
 * @param  result           计算结果
 * @return int 0 计算成功  -1 失败
 * @note null
 */
int move_ave_wma_d(move_ave_d_t *type, int T, double *result);
/**
 * @brief 计算指数移动平均(修正版)
 * @param  type
 * @param  wf               权重因子 一般接近1 等于1new将不参与本次计算，直至下次
 * @param  new              t时刻的值
 * @param  result           计算结果
 * @return int
 * @note wf越大 曲线越平滑瞬时响应弱，wf越小 瞬时响应强 曲线不稳
 */
int move_ave_ema_d(move_ave_d_t *type, float wf, double new, double *result);
/**
 * @brief 计算分形自适应移动平均
 * @param  type
 * @param  new              t时刻的值
 * @param  result           计算结果
 * @return int
 * @note 使用整个in缓冲区大小为T，在数据还没填充整个in缓冲区时均值输出为new
 */
int move_ave_frama_d(move_ave_d_t *type, double new, double *result);
/**
 * @brief 计算赫尔移动平均
 * @param  type
 * @param  T                窗口大小 最大等于 quantity
 * @param  result           计算结果
 * @return int 0 计算成功  -1 失败
 * @note null
 */
int move_ave_hma_d(move_ave_d_t *type, int T, double *result);
/**
 * @brief 返回计算结果
 * @param  type
 * @return double
 * @note null
 */
double move_ave_result(move_ave_d_t *type);
/***************************************Public Variables**********************************/


#endif
/* [] END OF FILE */
